import axios from "axios"
import * as changeCase from "change-case"
import { ApiInterface, Category } from "./types"
import ejs from "ejs"
import fs from "fs"
import path from "path"

import {
  isPostMethod,
  jsonSchemaToTypes,
  formatCode,
  convertToJsonSchema
} from "./utils"

interface ApiGeneratorOptions {
  baseUrl: string
  token: string
  apiTemplate?: string
  platform?: "yapi" | "apipost" | "swagger" // 添加平台选择
  projectId?: string // APIPost 专用的项目ID
}

class ApiGenerator {
  private opts: ApiGeneratorOptions
  private readonly outputDir = "api-gen"
  private readonly targetLanguage = "javascript"

  constructor(opts: ApiGeneratorOptions) {
    this.opts = opts
  }

  // 从URL中提取项目ID
  private extractProjectId(url: string): string | undefined {
    const match = url.match(/project_id=([^&]+)/)
    return match ? match[1] : undefined
  }

  // 重构数据结构为树形结构
  private restructureData(data: any): any {
    // 如果不是有效的 APIPost 数据结构，直接返回原数据
    if (
      !data ||
      !data.data ||
      !data.data.list ||
      !Array.isArray(data.data.list)
    ) {
      return data
    }

    const list = data.data.list
    const folderMap = new Map<string, any>()
    const apiMap = new Map<string, any[]>()

    // 分离文件夹和API
    list.forEach((item: any) => {
      if (item.target_type === "folder") {
        folderMap.set(item.target_id, {
          id: item.target_id,
          name: item.name,
          target_type: item.target_type,
          parent_id: item.parent_id,
          children: []
        })
      } else if (item.target_type === "api") {
        const parentId = item.parent_id
        if (!apiMap.has(parentId)) {
          apiMap.set(parentId, [])
        }
        apiMap.get(parentId)!.push(item)
      }
    })

    // 构建树结构
    const buildTree = (parentId: string = "0"): any[] => {
      const result: any[] = []

      // 添加当前层级的文件夹
      folderMap.forEach((folder) => {
        if (folder.parent_id === parentId) {
          // 递归添加子文件夹
          folder.children = buildTree(folder.id)

          // 添加当前文件夹下的API
          const apis = apiMap.get(folder.id) || []
          folder.children.push(...apis)

          result.push(folder)
        }
      })

      // 添加根级别的API（没有父文件夹的API）
      if (parentId === "0") {
        const rootApis = apiMap.get("0") || []
        result.push(...rootApis)
      }

      return result
    }

    // 构建新的数据结构
    const restructured = {
      code: data.code,
      msg: data.msg,
      data: buildTree(),
      time: data.time,
      extra_err: data.extra_err
    }

    return restructured
  }

  // 按第一层目录生成JSON文件到 output/json/
  private saveJsonToFiles(data: any): void {
    try {
      // 使用固定的输出目录

      // 重构数据结构
      const restructuredData = this.restructureData(data)

      // 如果没有有效的树形数据，就保存原始数据
      if (!restructuredData.data || !Array.isArray(restructuredData.data)) {
        console.log("数据格式无效，保存原始数据")
        const jsonDir = path.join(this.outputDir, "json")
        if (!fs.existsSync(jsonDir)) {
          fs.mkdirSync(jsonDir, { recursive: true })
        }
        fs.writeFileSync(
          path.join(jsonDir, "api-raw.json"),
          JSON.stringify(data, null, 2),
          "utf-8"
        )
        return
      }

      const jsonDir = path.join(this.outputDir, "json")
      if (!fs.existsSync(jsonDir)) {
        fs.mkdirSync(jsonDir, { recursive: true })
        console.log(`创建 JSON 输出目录: ${jsonDir}`)
      }

      // 按第一层目录和URL前缀生成文件
      const groupedApis = this.getGroupedApiData(data)

      for (const [groupName, urlGroups] of Object.entries(groupedApis)) {
        // 创建分组目录
        const safeDirName = groupName.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, "_")
        const groupJsonDir = path.join(jsonDir, safeDirName)
        if (!fs.existsSync(groupJsonDir)) {
          fs.mkdirSync(groupJsonDir, { recursive: true })
        }

        // 为每个URL前缀保存文件
        for (const [urlPrefix, apis] of Object.entries(urlGroups)) {
          if (apis.length === 0) continue

          const fileName = `${urlPrefix}.json`
          const filePath = path.join(groupJsonDir, fileName)
          fs.writeFileSync(filePath, JSON.stringify(apis, null, 2), "utf-8")
          console.log(`JSON 文件已保存: ${filePath}`)
        }
      }
    } catch (error) {
      console.error("保存 JSON 文件时出错:", error)
    }
  }

  async fetchApiList() {
    try {
      const platform = this.opts.platform || "yapi"
      console.log(
        `正在从 ${this.opts.baseUrl} 获取${platform === "apipost" ? "APIPost" : platform === "swagger" ? "Swagger" : "YAPI"} API数据...`
      )

      let apiUrl: string
      let requestConfig: any

      if (platform === "apipost") {
        // APIPost API端点 - project_id作为查询参数，api_token作为请求头
        apiUrl = this.opts.baseUrl
        requestConfig = {
          timeout: 5000,
          params: {
            project_id:
              this.opts.projectId ||
              this.extractProjectId(this.opts.baseUrl) ||
              "default"
          },
          headers: {
            api_token: this.opts.token,
            "Content-Type": "application/json"
          }
        }
      } else if (platform === "swagger") {
        // Swagger/OpenAPI API端点
        apiUrl = this.opts.baseUrl
        requestConfig = {
          timeout: 10000,
          headers: {
            "Content-Type": "application/json"
          }
        }
      } else {
        // YAPI API端点
        apiUrl = `${this.opts.baseUrl}/api/plugin/export`
        requestConfig = {
          timeout: 5000,
          params: {
            type: "json",
            status: "all",
            isWiki: "false",
            token: this.opts.token
          }
        }
      }

      const { data } = await axios.get(apiUrl, requestConfig)

      console.log("API响应数据结构:", {
        hasData: !!data,
        dataType: typeof data,
        isArray: Array.isArray(data),
        dataKeys: data ? Object.keys(data) : "no data",
        data: JSON.stringify(data)
      })

      // 根据平台解析不同的数据结构
      if (platform === "apipost") {
        return this.parseApipostData(data)
      } else if (platform === "swagger") {
        return this.parseSwaggerData(data)
      } else {
        return this.parseYapiData(data)
      }
    } catch (error) {
      console.error("获取接口数据时出错:", error)
      if (axios.isAxiosError(error)) {
        console.error("HTTP状态码:", error.response?.status)
        console.error("响应数据:", error.response?.data)
      }
      throw error
    }
  }

  // 解析APIPost数据
  private parseApipostData(data: any): Category[] {
    console.log("正在解析APIPost数据:", JSON.stringify(data, null, 2))

    // 保存 JSON 数据到文件
    this.saveJsonToFiles(data)

    if (!data || data.code !== 0) {
      console.warn(`APIPost数据格式无效或请求失败: ${data?.msg || "未知错误"}`)
      return []
    }

    // APIPost的成功响应结构通常是 { code: 0, data: { list: [...] } }
    const apiList = data.data?.list || data.data?.apis || []

    if (!Array.isArray(apiList) || apiList.length === 0) {
      console.warn("APIPost API列表为空")
      return []
    }

    // 将APIPost的API列表转换为Category格式
    return [
      {
        _id: 1,
        name: "APIPost APIs",
        desc: "从APIPost获取的API接口",
        list: apiList.map((api: any) => this.convertApipostApiToInterface(api)),
        add_time: Date.now(),
        up_time: Date.now(),
        _apiCodes: { codes: "", tsTypes: "" }
      }
    ]
  }

  // 将APIPost的API格式转换为标准接口格式
  private convertApipostApiToInterface(api: any): any {
    return {
      _id: api.id || api._id,
      title: api.name || api.title || api.path,
      status: api.status || "done",
      markdown: api.description || api.desc || "",
      path: api.path || api.url || "",
      method: api.method || "GET",
      project_id: api.project_id || 1,
      catid: api.category_id || 1,
      tag: api.tags || [],
      req_headers: api.req_headers || [],
      req_params: api.req_params || [],
      req_query: api.req_query || [],
      req_body_type: api.req_body_type || "none",
      req_body_is_json_schema: api.req_body_is_json_schema || false,
      req_body_form: api.req_body_form || [],
      req_body_other: api.req_body_other || "",
      res_body_type: api.res_body_type || "json",
      res_body_is_json_schema: api.res_body_is_json_schema || false,
      res_body: api.res_body || "",
      add_time: api.created_at || Date.now(),
      up_time: api.updated_at || Date.now(),
      uid: api.creator_id || 1
    }
  }

  // 解析YAPI数据
  private parseYapiData(data: any): Category[] {
    // 保存 JSON 数据到文件
    this.saveJsonToFiles(data)

    // 如果data是对象且包含list字段，尝试提取
    if (data && typeof data === "object" && !Array.isArray(data)) {
      if (data.list && Array.isArray(data.list)) {
        console.log("从data.list中提取到API列表")
        return data.list
      }
      if (data.data && Array.isArray(data.data)) {
        console.log("从data.data中提取到API列表")
        return data.data
      }
      if (data.apis && Array.isArray(data.apis)) {
        console.log("从data.apis中提取到API列表")
        return data.apis
      }
    }

    // 如果data本身就是数组，直接返回
    if (Array.isArray(data)) {
      return data
    }

    console.warn("无法识别的YAPI数据格式，返回空数组")
    return []
  }

  // 解析Swagger/OpenAPI数据
  private parseSwaggerData(data: any): Category[] {
    console.log("正在解析Swagger数据:", JSON.stringify(data, null, 2))

    // 保存 JSON 数据到文件
    this.saveJsonToFiles(data)

    if (!data || !data.paths) {
      console.warn("Swagger数据格式无效或缺少paths字段")
      return []
    }

    const apiList: any[] = []
    const paths = data.paths

    // 遍历所有路径
    Object.keys(paths).forEach(path => {
      const pathItem = paths[path]
      
      // 遍历每个路径的HTTP方法
      Object.keys(pathItem).forEach(method => {
        if (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'].includes(method.toLowerCase())) {
          const operation = pathItem[method]
          
          // 转换为标准ApiInterface格式
          const apiInterface = this.convertSwaggerOperationToInterface({
            path,
            method: method.toUpperCase(),
            operation,
            components: data.components || {}
          })
          
          apiList.push(apiInterface)
        }
      })
    })

    if (apiList.length === 0) {
      console.warn("Swagger API列表为空")
      return []
    }

    // 将Swagger的API列表转换为Category格式
    return [
      {
        _id: 1,
        name: "Swagger APIs",
        desc: "从Swagger/OpenAPI获取的API接口",
        list: apiList,
        add_time: Date.now(),
        up_time: Date.now(),
        _apiCodes: { codes: "", tsTypes: "" }
      }
    ]
  }

  // 将Swagger操作转换为标准接口格式
  private convertSwaggerOperationToInterface({ path, method, operation, components }: any): any {
    // 处理请求参数
    const reqParams: any[] = []
    const reqQuery: any[] = []
    const reqHeaders: any[] = []
    let reqBodyType = "none"
    let reqBodyOther = ""
    let reqBodyForm: any[] = []

    // 处理路径参数
    if (operation.parameters) {
      operation.parameters.forEach((param: any) => {
        if (param.in === "path") {
          reqParams.push({
            name: param.name,
            desc: param.description || "",
            example: param.example || "",
            type: param.schema?.type || "string",
            required: param.required ? "1" : "0"
          })
        } else if (param.in === "query") {
          reqQuery.push({
            name: param.name,
            desc: param.description || "",
            example: param.example || "",
            type: param.schema?.type || "string",
            required: param.required ? "1" : "0"
          })
        } else if (param.in === "header") {
          reqHeaders.push({
            name: param.name,
            value: param.example || "",
            desc: param.description || "",
            example: param.example || "",
            required: param.required ? "1" : "0"
          })
        }
      })
    }

    // 处理请求体
    if (operation.requestBody) {
      const requestBody = operation.requestBody
      const content = requestBody.content

      if (content) {
        if (content["application/json"]) {
          reqBodyType = "json"
          const schema = content["application/json"].schema
          reqBodyOther = JSON.stringify(this.resolveSwaggerSchema(schema, components))
        } else if (content["application/x-www-form-urlencoded"]) {
          reqBodyType = "form"
          const schema = content["application/x-www-form-urlencoded"].schema
          if (schema.properties) {
            Object.keys(schema.properties).forEach(key => {
              reqBodyForm.push({
                name: key,
                type: "text",
                desc: schema.properties[key].description || "",
                example: schema.properties[key].example || "",
                required: schema.required?.includes(key) ? "1" : "0"
              })
            })
          }
        }
      }
    }

    // 处理响应体
    let resBody = ""
    if (operation.responses) {
      const successResponse = operation.responses["200"] || operation.responses["201"] || operation.responses["default"]
      if (successResponse && successResponse.content && successResponse.content["application/json"]) {
        const schema = successResponse.content["application/json"].schema
        resBody = JSON.stringify(this.resolveSwaggerSchema(schema, components))
      }
    }

    return {
      _id: Math.random().toString(36).substr(2, 9),
      title: operation.summary || operation.operationId || `${method} ${path}`,
      status: "done",
      markdown: operation.description || "",
      path: path,
      method: method,
      project_id: 1,
      catid: 1,
      tag: operation.tags || [],
      req_headers: reqHeaders,
      req_params: reqParams,
      req_query: reqQuery,
      req_body_type: reqBodyType,
      req_body_is_json_schema: true,
      req_body_form: reqBodyForm,
      req_body_other: reqBodyOther,
      res_body_type: "json",
      res_body_is_json_schema: true,
      res_body: resBody,
      add_time: Date.now(),
      up_time: Date.now(),
      uid: 1
    }
  }

  // 解析Swagger schema引用
  private resolveSwaggerSchema(schema: any, components: any): any {
    if (!schema) return {}

    // 处理$ref引用
    if (schema.$ref) {
      const refPath = schema.$ref.replace('#/', '').split('/')
      let refSchema = components
      
      try {
        for (const path of refPath) {
          if (refSchema && typeof refSchema === 'object' && path in refSchema) {
            refSchema = refSchema[path]
          } else {
            console.warn(`无法找到引用路径: ${schema.$ref}`)
            return { type: "object", description: "无法解析的引用" }
          }
        }
        
        return this.resolveSwaggerSchema(refSchema, components)
      } catch (error) {
        console.warn(`解析引用时出错: ${schema.$ref}`, error)
        return { type: "object", description: "解析引用时出错" }
      }
    }

    // 处理数组类型
    if (schema.type === "array" && schema.items) {
      return {
        type: "array",
        items: this.resolveSwaggerSchema(schema.items, components)
      }
    }

    // 处理对象类型
    if (schema.type === "object" && schema.properties) {
      const resolvedProperties: any = {}
      Object.keys(schema.properties).forEach(key => {
        resolvedProperties[key] = this.resolveSwaggerSchema(schema.properties[key], components)
      })
      
      return {
        type: "object",
        properties: resolvedProperties,
        required: schema.required || []
      }
    }

    // 返回基本类型
    return {
      type: schema.type || "string",
      description: schema.description,
      example: schema.example
    }
  }

  // 将字符串转换为驼峰命名法
  private toCamelCase(str: string): string {
    return str
      .replace(/[-_]/g, ' ')  // 将连字符和下划线替换为空格
      .split(' ')
      .map((word, index) => {
        if (index === 0) {
          return word.toLowerCase()
        }
        return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
      })
      .join('')
  }

  // 生成 API 方法代码
  async generateApiMethods(apiList: ApiInterface[]) {
    let apiMethods = []
    let defaultApiTemplate = `
      /**
      * <%= title %>
      * @method <%= method %>
      * @path <%= path %>
      */
      export async function <%= methodName %>(params){
        return request({
          url: '<%= path %>',
          method: '<%= method.toLowerCase() %>',
          data: params
        })
      }
    `
    for (let api of apiList) {
      let requestJsonSchema: any
      const {
        path,
        method,
        title,
        req_body_other,
        res_body,
        req_body_type,
        req_body_form,
        req_query,
        req_params
      } = api
      // 只取问号前面的部分作为函数名
      const pathWithoutQuery = path.split("?")[0]
      
      // 根据URL层级生成简化的函数名
      const urlParts = pathWithoutQuery.split("/").filter(part => part.length > 0)
      let pathName: string
      
      if (urlParts.length >= 2) {
        // 对于 /admin-api/system/dept/create 这样的路径
        // 倒数第二层作为资源名，最后一层作为操作名：dept + create
        const resourceName = urlParts[urlParts.length - 2] // dept
        const actionName = urlParts[urlParts.length - 1]  // create
        pathName = `${resourceName}_${actionName}`
      } else if (urlParts.length === 1) {
        // 对于单层路径：/admin-api
        pathName = urlParts[0] // admin-api
      } else {
        // 空路径的情况
        pathName = "api"
      }
      
      // 确保路径名是合法的JavaScript标识符
      pathName = pathName
        .replace(/[^a-zA-Z0-9_-]/g, "_")  // 将所有非字母数字下划线连字符字符替换为下划线
        .replace(/_+/g, "_")            // 将多个连续下划线替换为单个下划线
        .replace(/^_|_$/g, "")          // 移除开头和结尾的下划线
      
      // 生成最终的函数名：HTTP方法 + 驼峰命名的路径
      const httpMethod = method.toLowerCase()
      const camelCasePath = this.toCamelCase(pathName)
      const methodName = `${httpMethod}${camelCasePath.charAt(0).toUpperCase()}${camelCasePath.slice(1)}`
      if (isPostMethod(method)) {
        switch (req_body_type) {
          case "form":
            requestJsonSchema = convertToJsonSchema(req_body_form)
            break
          case "json":
            if (req_body_other) {
              requestJsonSchema = JSON.parse(req_body_other)
              if (requestJsonSchema.type === "object") {
                // 将 additionalProperties 设为 false
                requestJsonSchema.additionalProperties = false
              }
            }
            break
          default:
            break
        }
      }

      // 处理查询数据
      if (req_query && req_query.length > 0) {
        const queryJsonSchema = convertToJsonSchema(req_query)
        if (requestJsonSchema) {
          requestJsonSchema.properties = {
            ...requestJsonSchema.properties,
            ...queryJsonSchema.properties
          }
          requestJsonSchema.required = [
            ...(Array.isArray(requestJsonSchema.required)
              ? requestJsonSchema.required
              : []),
            ...(Array.isArray(queryJsonSchema.required)
              ? queryJsonSchema.required
              : [])
          ]
        } else {
          requestJsonSchema = queryJsonSchema
        }
      }

      // 处理路径参数
      if (req_params && req_params.length) {
        const paramsJsonSchema = convertToJsonSchema(req_params)
        if (requestJsonSchema) {
          requestJsonSchema.properties = {
            ...requestJsonSchema.properties,
            ...paramsJsonSchema.properties
          }
          requestJsonSchema.required = [
            ...(Array.isArray(requestJsonSchema.required)
              ? requestJsonSchema.required
              : []),
            ...(Array.isArray(paramsJsonSchema.required)
              ? paramsJsonSchema.required
              : [])
          ]
        } else {
          requestJsonSchema = paramsJsonSchema
        }
      }

      const requestType = changeCase.pascalCase(`Request_${methodName}`)
      const responseType = changeCase.pascalCase(`Response_${methodName}`)
      const requestTypeDef = await jsonSchemaToTypes(
        JSON.stringify(requestJsonSchema),
        requestType
      )
      const responseTypeDef = await jsonSchemaToTypes(res_body, responseType)

      const apiCode = ejs.render(this.opts?.apiTemplate || defaultApiTemplate, {
        title,
        method,
        path,
        methodName,
        requestTypeDef,
        responseTypeDef,
        requestType,
        responseType
      })

      const tsTypesCode = `
        ${requestTypeDef}
        ${responseTypeDef}
      `
      apiMethods.push(apiCode)

      // 固定使用JavaScript，不需要TypeScript类型
    }
    const apiFormatCode = await formatCode(apiMethods.join("\n"))

    // 在代码前添加 import 语句
    const importStatement = 'import request from "@/request";\n\n'
    const finalApiCode = apiFormatCode ? importStatement + apiFormatCode : ""

    return {
      codes: finalApiCode,
      tsTypes: "" // 固定使用JavaScript，不需要TypeScript类型
    }
  }

  // 获取分组的API数据，按第一层文件夹和URL前缀双重分类
  private getGroupedApiData(data: any): {
    [groupName: string]: { [urlPrefix: string]: any[] }
  } {
    const platform = this.opts.platform || "yapi"
    const groupedApis: { [groupName: string]: { [urlPrefix: string]: any[] } } =
      {}

    if (platform === "swagger") {
      // Swagger数据是扁平结构，直接从paths中提取
      if (!data || !data.paths) {
        return groupedApis
      }

      const apiList: any[] = []
      const paths = data.paths

      // 遍历所有路径
      Object.keys(paths).forEach(path => {
        const pathItem = paths[path]
        
        // 遍历每个路径的HTTP方法
        Object.keys(pathItem).forEach(method => {
          if (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'].includes(method.toLowerCase())) {
            const operation = pathItem[method]
            
            // 转换为标准ApiInterface格式
            const apiInterface = this.convertSwaggerOperationToInterface({
              path,
              method: method.toUpperCase(),
              operation,
              components: data.components || {}
            })
            
            apiInterface.target_type = "api"
            apiInterface.url = path
            apiList.push(apiInterface)
          }
        })
      })

      // 使用新的层级分组逻辑
      const hierarchyGrouped = this.groupApisByUrlHierarchy(apiList)
      
      // 将层级分组结果合并到主分组中
      Object.keys(hierarchyGrouped).forEach(groupName => {
        groupedApis[groupName] = hierarchyGrouped[groupName]
      })
    } else {
      // APIPost和YAPI的树形结构处理
      const restructuredData = this.restructureData(data)

      if (!restructuredData.data || !Array.isArray(restructuredData.data)) {
        return groupedApis
      }

      restructuredData.data.forEach((firstLevelItem: any) => {
        if (firstLevelItem.target_type === "folder") {
          const groupName = firstLevelItem.name || "未命名分组"
          const apis = this.getAllApisFromFolder(firstLevelItem)
          
          // 使用新的层级分组逻辑
          const hierarchyGrouped = this.groupApisByUrlHierarchy(apis)
          
          // 将层级分组结果合并到主分组中
          Object.keys(hierarchyGrouped).forEach(hierarchyGroupName => {
            // 如果层级分组名称与文件夹名称不同，则使用层级分组名称
            const finalGroupName = hierarchyGroupName !== groupName ? hierarchyGroupName : groupName
            groupedApis[finalGroupName] = hierarchyGrouped[hierarchyGroupName]
          })
        } else {
          // 根级别的API
          const rootApis = [firstLevelItem]
          
          // 使用新的层级分组逻辑
          const hierarchyGrouped = this.groupApisByUrlHierarchy(rootApis)
          
          // 将层级分组结果合并到主分组中
          Object.keys(hierarchyGrouped).forEach(groupName => {
            groupedApis[groupName] = hierarchyGrouped[groupName]
          })
        }
      })
    }

    return groupedApis
  }

  // 按 URL 层级分组 API - 公共方法
  private groupApisByUrlHierarchy(apis: any[]): { [groupName: string]: { [urlPrefix: string]: any[] } } {
    const grouped: { [groupName: string]: { [urlPrefix: string]: any[] } } = {}

    apis.forEach((api: any) => {
      if (api.target_type === "api" && api.url) {
        const urlParts = api.url
          .split("/")
          .filter((part: string) => part.length > 0)
        
        if (urlParts.length === 0) return

        let groupName: string
        let urlPrefix: string

        if (urlParts.length === 1) {
          // 只有一层：/admin-api -> group: "", prefix: "admin-api"
          groupName = ""
          urlPrefix = urlParts[0]
        } else if (urlParts.length === 2) {
          // 两层：/admin-api/system -> group: "admin-api", prefix: "system"
          groupName = urlParts[0]
          urlPrefix = urlParts[1]
        } else {
          // 三层或更多：/admin-api/system/dept/create -> group: "admin-api/system", prefix: "dept"
          // 倒数第二层作为文件名，最后一层作为函数名的一部分
          groupName = urlParts.slice(0, -2).join("/")
          urlPrefix = urlParts[urlParts.length - 2]
        }

        // 确保分组存在
        if (!grouped[groupName]) {
          grouped[groupName] = {}
        }
        if (!grouped[groupName][urlPrefix]) {
          grouped[groupName][urlPrefix] = []
        }
        grouped[groupName][urlPrefix].push(api)
      }
    })

    return grouped
  }

  // 按 URL 前缀分组 API（保留原方法以兼容）
  private groupApisByUrlPrefix(apis: any[]): { [urlPrefix: string]: any[] } {
    const grouped: { [urlPrefix: string]: any[] } = {}

    apis.forEach((api: any) => {
      if (api.target_type === "api" && api.url) {
        // 提取 URL 的第一部分作为前缀
        const urlParts = api.url
          .split("/")
          .filter((part: string) => part.length > 0)
        const urlPrefix = urlParts.length > 0 ? urlParts[0] : "unknown"

        if (!grouped[urlPrefix]) {
          grouped[urlPrefix] = []
        }
        grouped[urlPrefix].push(api)
      }
    })

    return grouped
  }

  // 递归获取文件夹中的所有API
  private getAllApisFromFolder(folder: any): any[] {
    const apis: any[] = []

    if (folder.children && Array.isArray(folder.children)) {
      folder.children.forEach((child: any) => {
        if (child.target_type === "api") {
          apis.push(child)
        } else if (child.target_type === "folder") {
          // 递归获取子文件夹中的API
          apis.push(...this.getAllApisFromFolder(child))
        }
      })
    }

    return apis
  }

  async generateCode() {
    const apiList: Category[] = await this.fetchApiList()

    // 添加数据验证
    if (!apiList || !Array.isArray(apiList)) {
      console.error("API数据格式错误，期望数组格式")
      console.log("实际返回数据:", apiList)
      return { grouped: {}, categories: [] }
    }

    if (apiList.length === 0) {
      console.error("未找到 API 数据")
      return { grouped: {}, categories: [] }
    }

    // 验证每个分类对象的结构
    for (let apis of apiList) {
      if (!apis || !apis.list || !Array.isArray(apis.list)) {
        console.warn(`跳过无效的分类数据:`, apis)
        continue
      }

      try {
        apis._apiCodes = await this.generateApiMethods(apis.list)
      } catch (error) {
        console.error(`处理分类 ${apis.name || "unknown"} 时出错:`, error)
        // 设置默认值避免后续错误
        apis._apiCodes = {
          codes: "",
          tsTypes: ""
        }
      }
    }

    return { grouped: {}, categories: apiList }
  }

  // 生成按分组的代码
  async generateGroupedCode() {
    // 首先获取原始数据
    const platform = this.opts.platform || "yapi"
    let rawData: any

    try {
      const { data } = await this.fetchApiData()
      rawData = data
    } catch (error) {
      console.error("获取API数据失败:", error)
      return { grouped: {}, categories: [] }
    }

    // 获取分组的API数据
    const groupedApis = this.getGroupedApiData(rawData)
    const groupedResults: {
      [groupName: string]: {
        [urlPrefix: string]: { codes: string; tsTypes: string }
      }
    } = {}

    // 为每个分组和URL前缀生成代码
    for (const [groupName, urlGroups] of Object.entries(groupedApis)) {
      groupedResults[groupName] = {}

      for (const [urlPrefix, apis] of Object.entries(urlGroups)) {
        if (apis.length === 0) continue

        try {
          // 根据平台转换格式
          let convertedApis: any[]
          if (this.opts.platform === "apipost") {
            convertedApis = apis.map((api) =>
              this.convertApipostApiToInterface(api)
            )
          } else if (this.opts.platform === "swagger") {
            // Swagger数据已经是标准格式，直接使用
            convertedApis = apis
          } else {
            // YAPI数据已经是标准格式，直接使用
            convertedApis = apis
          }
          groupedResults[groupName][urlPrefix] =
            await this.generateApiMethods(convertedApis)
        } catch (error) {
          console.error(`处理分组 ${groupName}/${urlPrefix} 时出错:`, error)
          groupedResults[groupName][urlPrefix] = {
            codes: "",
            tsTypes: ""
          }
        }
      }
    }

    return { grouped: groupedResults, categories: [] }
  }

  // 获取原始API数据
  private async fetchApiData() {
    const platform = this.opts.platform || "yapi"
    console.log(
      `正在从 ${this.opts.baseUrl} 获取${platform === "apipost" ? "APIPost" : platform === "swagger" ? "Swagger" : "YAPI"} API数据...`
    )

    let apiUrl: string
    let requestConfig: any

    if (platform === "apipost") {
      // APIPost API端点 - project_id作为查询参数，api_token作为请求头
      apiUrl = this.opts.baseUrl
      requestConfig = {
        timeout: 5000,
        params: {
          project_id:
            this.opts.projectId ||
            this.extractProjectId(this.opts.baseUrl) ||
            "default"
        },
        headers: {
          api_token: this.opts.token,
          "Content-Type": "application/json"
        }
      }
    } else if (platform === "swagger") {
      // Swagger/OpenAPI API端点
      apiUrl = this.opts.baseUrl
      requestConfig = {
        timeout: 10000,
        headers: {
          "Content-Type": "application/json"
        }
      }
    } else {
      // YAPI API端点
      apiUrl = `${this.opts.baseUrl}/api/plugin/export`
      requestConfig = {
        timeout: 5000,
        params: {
          type: "json",
          status: "all",
          isWiki: "false",
          token: this.opts.token
        }
      }
    }

    const res = await axios.get(apiUrl, requestConfig)
    // console.log(res.data.data, "请求列表")

    return res
  }
}

export default ApiGenerator
